package com.eg.egent.example.common;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

import org.apache.shiro.codec.Hex;
import org.apache.shiro.crypto.AesCipherService;

import com.alibaba.fastjson.JSONObject;

import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Request.Builder;
import okhttp3.Response;

public class ApiUtil {

	/**
	 * 
	 * @param encrypt
	 *            加密算法
	 * @param signMethod
	 *            签名算法
	 * @param taskDesc
	 *            请求操作描述信息
	 * @param mainContent
	 *            业务参数封装成的jsonobject
	 */
	public static void excute(Integer encrypt, Integer signMethod, String taskDesc, JSONObject mainContent) {
		String mainContentStr = getMainContentStr(encrypt, mainContent);
		String timestamp = getTimeStamp();
		Map<String, Object> signParams = generateSignParams(Constants.APP_ID, encrypt, signMethod, timestamp,
				mainContentStr);

		String sign = null;
		try {
			sign = HttpSignCaculate.signEIOTRequest(signParams, Constants.SECRET_KEY, signMethod);
		} catch (IOException e1) {
			e1.printStackTrace();
		} catch (NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		}
		String taskResult = post(Constants.EGENT_API_URL, Constants.APP_ID, timestamp, encrypt, signMethod,
				sign, mainContentStr);
		JSONObject taskResultObject = JSONObject.parseObject(taskResult);
		Integer responseResultCode = taskResultObject.getInteger("code");
		if (ResultCode.SUCCESS == responseResultCode) {
			System.out.println(taskDesc + "成功......");
			System.out.println(taskResult);
		}else if(ResultCode.TASK_NOT_COMPLETE == responseResultCode){
			System.out.println(taskDesc + "尚未完成，请稍后根据task_id查看"+taskDesc+"指令详细处理结果......");
			System.out.println(taskResult);
		} else {
			System.out.println(taskDesc + "失败......");
			System.out.println(taskResult);
		}
	}

	/**
	 * 往服务端发送post请求
	 * 
	 * @param url
	 *            请求url
	 * @param appId
	 *            应用号
	 * @param timestamp
	 *            请求时间
	 * @param encrypt
	 *            加密算法
	 * @param signMethod
	 *            签名算法
	 * @param sign
	 *            生成的签名
	 * @param mainContentStr
	 *            业务参数组成的json格式的字符串
	 * @return
	 */
	private static String post(String url, String appId, String timestamp, Integer encrypt,
			Integer signMethod, String headerSign, String paramMainContentStr) {
		// 创建一个OkHttpClient对象
		OkHttpClient okHttpClient = new OkHttpClient();

		FormBody.Builder formBuilder = new FormBody.Builder();
		formBuilder.add("timestamp", timestamp);
		formBuilder.add("main_content", paramMainContentStr);
		Builder builder = new Request.Builder();
		builder.url(url);
		builder.addHeader("app_id", appId);
		builder.addHeader("encrypt", encrypt + "");
		builder.addHeader("sign_method", signMethod + "");
		builder.addHeader("sign", headerSign);
		builder.post(formBuilder.build());

		Request request = builder.build();
		// 发送请求获取响应
		try {
			Response response = okHttpClient.newCall(request).execute();
			// 判断请求是否成功
			if (response.isSuccessful()) {
				// 打印服务端返回结果
				// Log.i(TAG,response.body().string());
				String responseBodyStr = response.body().string();
				return responseBodyStr;
			} else {
				return "response failed";
			}
		} catch (IOException e) {
			return "io exception";
		}
	}

	private static Map<String, Object> generateSignParams(String appId, Integer encrypt, Integer signMethod, String timestamp, String mainContentStr) {
		Map<String, Object> signParams = new HashMap<String, Object>();
		signParams.put("app_id", appId);
		signParams.put("encrypt", encrypt);
		signParams.put("sign_method", signMethod);
		signParams.put("timestamp", timestamp);
		signParams.put("main_content", mainContentStr);
		return signParams;

	}

	/**
	 * 查询下行指令的详细信息
	 * 
	 * @param taskId
	 *            欲查询的下行指令ID
	 * @param encrypt
	 *            查询下行指令详细信息请求的加密算法
	 * @param signMethod
	 *            查询下行指令详细信息请求的签名算法
	 * @return
	 */
	public static String getTaskDetail(String taskId, Integer encrypt, Integer signMethod) {

		JSONObject taskDetailMainContent = new JSONObject();
		taskDetailMainContent.put("method", Method.TASK_DETAIL_GET);
		taskDetailMainContent.put("task_id", taskId);

		String taskDetailMainContentStr = getMainContentStr(encrypt, taskDetailMainContent);
		String taskDetailTimeStamp = getTimeStamp();
		Map<String, Object> signParams = generateSignParams(Constants.APP_ID, encrypt, signMethod,
				taskDetailTimeStamp, taskDetailMainContentStr);

		String taskDetailSign = null;
		try {
			taskDetailSign = HttpSignCaculate.signEIOTRequest(signParams, Constants.SECRET_KEY, signMethod);
		} catch (IOException e1) {
			e1.printStackTrace();
		} catch (NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		}

		return post(Constants.EGENT_API_URL, Constants.APP_ID, taskDetailTimeStamp, encrypt, signMethod,
				taskDetailSign, taskDetailMainContentStr);
	}

	/**
	 * 获得main_content中的字符串参数
	 * 
	 * @param encrypt
	 *            加密算法
	 * @param mainContent
	 *            业务参数组成的json格式字符串
	 * @return
	 */
	private static String getMainContentStr(Integer encrypt, JSONObject mainContent) {
		String mainContentStr;
		if (Constants.ENCRYPT_AES == encrypt) {
			AesCipherService aesCipherService = new AesCipherService();
			String encryptnetWorkOpenMainContent = aesCipherService
					.encrypt(mainContent.toJSONString().getBytes(), Hex.decode(Constants.SECRET_KEY)).toHex();
			mainContentStr = encryptnetWorkOpenMainContent;
		} else {
			mainContentStr = mainContent.toJSONString();
		}
		return mainContentStr;
	}

	/**
	 * 获取当前时间
	 * @return
	 */
	private static String getTimeStamp() {
		LocalDateTime localtDateAndTime = LocalDateTime.now();
		ZonedDateTime dateAndTimeInShanghai = ZonedDateTime.of(localtDateAndTime,
				ZoneId.of(ZoneId.SHORT_IDS.get("CTT")));
		return dateAndTimeInShanghai.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
	}

	/**
	 * 查看任务处理状态
	 * @param taskDetailData
	 * @param operateDesc
	 */
	public static void showTaskStatus(JSONObject taskDetailData, String operateDesc) {
		Integer status = taskDetailData.getInteger("status");
		if (Constants.STATE_CREATE == status) {
			System.out.println("Egent已接收并创建该指令......");
		} else if (Constants.STATE_WAIT == status) {
			System.out.println("Egent已创建该指令，并等待执行......");
		} else if (Constants.STATE_PROCESSING == status) {
			System.out.println("主控器已接收，并正在处理该指令......");
		} else if (Constants.STATE_COMPLETE == status) {
			System.out.println("主控器已完成该指令的执行......");
			Integer resultCode = taskDetailData.getInteger("result_code");
			if (Constants.RESULTCODE_OK == resultCode) {
				System.out.println("下行操作"+taskDetailData.getString("operate")+"成功......");
			} else {
				System.out.println("下行操作"+taskDetailData.getString("operate")+"失败......失败的错误码为：" + resultCode);
			}
		} else if (Constants.STATE_TIMEOUT == status) {
			System.out.println("该指令处理超时......");
		} else if (Constants.STATE_EXCEPTION == status) {
			System.out.println("该指令处理异常......");
		}
	}

}
